using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GomokuGame.AI
{
    /// <summary>
    /// 初级AI - 随机落子
    /// </summary>
    public class BeginnerAI : IAIAlgorithm
    {
        private readonly Random random = new Random();
        private int thinkingProgress = 0;

        public AIDifficulty Difficulty => AIDifficulty.Beginner;
        public string Name => "初级AI";

        public async Task<Move> CalculateNextMoveAsync(PieceType[,] board, PieceType currentPlayer, int maxThinkingTime = 5000)
        {
            return await Task.Run(() => CalculateNextMove(board, currentPlayer, maxThinkingTime));
        }

        public Move CalculateNextMove(PieceType[,] board, PieceType currentPlayer, int maxThinkingTime = 5000)
        {
            var startTime = DateTime.Now;
            thinkingProgress = 0;

            // 获取所有可用的空位置
            var availableMoves = GetAvailableMoves(board);
            
            if (availableMoves.Count == 0)
                return null;

            // 优先选择棋盘中心位置
            var centerMoves = availableMoves.Where(m => 
                Math.Abs(m.Row - 7) <= 2 && Math.Abs(m.Col - 7) <= 2).ToList();
            
            List<Position> preferredMoves;
            if (centerMoves.Count > 0)
            {
                preferredMoves = centerMoves;
            }
            else
            {
                // 如果没有中心位置，选择靠近已有棋子的位置
                preferredMoves = availableMoves.Where(m => HasNearbyPieces(board, m)).ToList();
                if (preferredMoves.Count == 0)
                {
                    preferredMoves = availableMoves;
                }
            }

            // 模拟思考时间
            SimulateThinkingTime(maxThinkingTime);

            // 从优先位置中随机选择一个
            var randomIndex = random.Next(preferredMoves.Count);
            var selectedMove = preferredMoves[randomIndex];

            var thinkingTime = (int)(DateTime.Now - startTime).TotalMilliseconds;
            thinkingProgress = 100;

            return new Move(selectedMove.Row, selectedMove.Col, currentPlayer, 0, thinkingTime);
        }

        public int GetThinkingProgress()
        {
            return thinkingProgress;
        }

        public void Reset()
        {
            thinkingProgress = 0;
        }

        /// <summary>
        /// 获取所有可用的空位置
        /// </summary>
        /// <param name="board">棋盘状态</param>
        /// <returns>可用位置列表</returns>
        private List<Position> GetAvailableMoves(PieceType[,] board)
        {
            var moves = new List<Position>();
            int boardSize = board.GetLength(0);

            for (int row = 0; row < boardSize; row++)
            {
                for (int col = 0; col < boardSize; col++)
                {
                    if (board[row, col] == PieceType.Empty)
                    {
                        moves.Add(new Position(row, col));
                    }
                }
            }

            return moves;
        }

        /// <summary>
        /// 模拟思考时间
        /// </summary>
        /// <param name="maxTime">最大思考时间</param>
        private void SimulateThinkingTime(int maxTime)
        {
            var actualTime = random.Next(100, Math.Min(maxTime, 1000)); // 100ms到1秒之间
            var steps = 10;
            var stepTime = actualTime / steps;

            for (int i = 0; i < steps; i++)
            {
                System.Threading.Thread.Sleep(stepTime);
                thinkingProgress = (i + 1) * 100 / steps;
            }
        }

        /// <summary>
        /// 检查位置附近是否有棋子
        /// </summary>
        /// <param name="board">棋盘状态</param>
        /// <param name="position">位置</param>
        /// <returns>是否有附近棋子</returns>
        private bool HasNearbyPieces(PieceType[,] board, Position position)
        {
            int boardSize = board.GetLength(0);
            
            for (int row = Math.Max(0, position.Row - 2); row <= Math.Min(boardSize - 1, position.Row + 2); row++)
            {
                for (int col = Math.Max(0, position.Col - 2); col <= Math.Min(boardSize - 1, position.Col + 2); col++)
                {
                    if (board[row, col] != PieceType.Empty)
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 位置结构
        /// </summary>
        private struct Position
        {
            public int Row { get; set; }
            public int Col { get; set; }

            public Position(int row, int col)
            {
                Row = row;
                Col = col;
            }
        }
    }
} 